package com.ciei.dpagm.util;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 
 */
public class ClassUtil {

    /**
     * 获取字段
     * @param cls
     * @param fieldName
     * @return
     */
    public static Field getField(Class cls, String fieldName){
        Field match1 = null;
        List list = new ArrayList();
        list.add(cls);
        list.addAll(ClassUtils.getAllInterfaces(cls));
        list.addAll(ClassUtils.getAllSuperclasses(cls));
        Iterator intf1 = list.iterator();
        while(intf1.hasNext()) {
            try {
                Field ex = ((Class)intf1.next()).getDeclaredField(fieldName);
                if(match1 != null) {
                    throw new IllegalArgumentException("Reference to field " + fieldName + " is ambiguous relative to " + cls + "; a matching field exists on two or more implemented interfaces.");
                }
                match1 = ex;
            } catch (NoSuchFieldException var6) {
                ;
            }
        }
        return match1;
    }

    /**
     * 复制sour的值到target
     * @param target 目标实体类
     * @param source 源实体类
     * @param isCover  0:源属性值非空，且目标属性值为空，则复制；1：源属性值非空，则复制；2：一定复制
     * @return target
     */
    public static Object copy(Object target, Object source, int isCover) {
        Field[] fields = source.getClass().getDeclaredFields();
        for (Field field : fields) {
            String propertyName = field.getName();
            Object sourcePropertyValue = getProperty(source, propertyName);
            if (isCover==1) {
                if (sourcePropertyValue != null) {
                    Object setProperty = setProperty(target, propertyName, sourcePropertyValue);
                }
            } else if (isCover == 0) {
                if (getProperty(target, propertyName) == null && sourcePropertyValue != null) {
                    Object setProperty = setProperty(target, propertyName, sourcePropertyValue);
                }
            } else {
                Object setProperty = setProperty(target, propertyName, sourcePropertyValue);
            }
        }
        return target;
    }

    /**
     * 得到值
     * 
     * @param bean
     * @param propertyName
     * @return
     */
    private static Object getProperty(Object bean, String propertyName) {
        Class clazz = bean.getClass();
        try {
            Field field = clazz.getDeclaredField(propertyName);
            Method method = clazz.getDeclaredMethod(
                    getGetterName(field.getName()), new Class[] {});
            return method.invoke(bean, new Object[] {});
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 给bean赋值
     * 
     * @param bean
     * @param propertyName
     * @param value
     * @return
     */
    private static Object setProperty(Object bean, String propertyName,
            Object value) {
        Class clazz = bean.getClass();
        try {
            Field field = clazz.getDeclaredField(propertyName);
            Method method = clazz.getDeclaredMethod(
                    getSetterName(field.getName()),
                    new Class[] { field.getType() });
            return method.invoke(bean, new Object[] { value });
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 根据变量名得到get方法
     * 
     * @param propertyName
     * @return
     */
    private static String getGetterName(String propertyName) {
        String method = "get" + propertyName.substring(0, 1).toUpperCase()
                + propertyName.substring(1);
        return method;
    }

    /**
     * 得到setter方法
     * 
     * @param propertyName
     *            变量名
     * @return
     */
    private static String getSetterName(String propertyName) {
        String method = "set" + propertyName.substring(0, 1).toUpperCase()
                + propertyName.substring(1);
        return method;
    }
    
    
    /**
     * 把对象属性值为空字符串的属性值设为null
     * 
     * @param obj
     * @return
     */
    public static Object emptyStringConvertNull(Object obj) {
    	 Field[] fields = obj.getClass().getDeclaredFields();
         for (int i = 0, j = fields.length; i < j; i++) {
        	 if(fields[i].getGenericType().toString().equals("class java.lang.String")) {
        		 String propertyName = fields[i].getName();
        		 String propertyValue =(String) getProperty(obj, propertyName);
        		 if(propertyValue!=null && propertyValue.trim().isEmpty()) {
        			 setProperty(obj, propertyName,null);
        		 }
        	 }
         }
         return obj;
    }

    /**
     * 给bean的单个field赋值
     * @param bean
     * @param jsonData 键值对
     * @param fieldKeyName field和json的key
     */
    public void setProperty(Object bean, Map<String,Object> jsonData, String[] fieldKeyName){
        String fieldName = fieldKeyName[0];//属性名
        String keyName = fieldKeyName[1];//json的key
        String fieldValue = (String) jsonData.get(keyName);
        if(StringUtils.isNotBlank(fieldValue)){
            String upperField = fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);// 将属性的首字符大写，方便构造get，set方法
            Class clazz = bean.getClass();
            try {
                Field field = clazz.getDeclaredField(fieldName);
                String type = field.getGenericType().toString();//获取属性的类型
                if (type.equals("class java.lang.String")) { // 如果type是类类型，则前面包含"class "，后面跟类名
                    Method method = clazz.getDeclaredMethod("set"+upperField,String.class);
                    method.invoke(bean,fieldValue);
                }
                if (type.equals("class java.lang.Integer")) {
                    Method method = clazz.getDeclaredMethod("set"+upperField,Integer.class);
                    method.invoke(bean,Integer.parseInt(fieldValue));
                }
                if (type.equals("class java.lang.Long")) {
                    Method method = clazz.getDeclaredMethod("set"+upperField,Long.class);
                    method.invoke(bean,Long.valueOf(fieldValue));
                }
                if (type.equals("class java.lang.Double")) {
                    Method method = clazz.getDeclaredMethod("set"+upperField,Double.class);
                    method.invoke(bean,Double.valueOf(fieldValue));
                }
            } catch (NoSuchFieldException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 对象属性拷贝 <br>
     * 将源对象的属性拷贝到目标对象
     *
     * @param source 源对象
     * @param target 目标对象
     */
    public static void copyProperties(Object source, Object target) {
        try {
            BeanUtils.copyProperties(source, target);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param input 输入集合
     * @param clzz  输出集合类型
     * @param <E>   输入集合类型
     * @param <T>   输出集合类型
     * @return 返回集合
     */
    public static <E, T> List<T> convertList2List(List<E> input, Class<T> clzz) {
        List<T> output = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(input)) {
            for (E source : input) {
                T target = BeanUtils.instantiate(clzz);
                copyProperties(source, target);
                output.add(target);
            }
        }
        return output;
    }

}

